from counterpoint.exceptions import Http403
from counterpoint.forms import PostForm, ForumUserForm
from counterpoint.helpers import render_response
from counterpoint.models import Forum, Post, ForumUser
from datetime import datetime, timedelta
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.views.generic import list_detail


__all__ = ('forum_index', 'thread_view', 'new_post', 'edit', 'edit_user', )


def forum_index(request, forum_id):
    forum = get_object_or_404(Forum, pk=forum_id)
    kwargs = {
        'queryset': forum.posts.order_by('-sticky', '-last_reply_time'),
        'allow_empty': True,
        'template_name': 'counterpoint/thread_list.html',
        'extra_context': {'forum': forum},
    }
    return list_detail.object_list(request, **kwargs)


def thread_view(request, forum_id, thread_id):
    forum = get_object_or_404(Forum, pk=forum_id)
    thread = get_object_or_404(Post, pk=thread_id)
    posts = Post.objects.filter(Q(id=thread_id) | Q(parent_post=thread))
    thread.views += 1
    thread.save()
    kwargs = {
        'queryset': posts,
        'paginate_by': 40,
        'extra_context': {'forum': forum, 'thread': thread},
    }
    return list_detail.object_list(request, **kwargs)


def new_post(request, forum_id, thread_id=None):
    forum = get_object_or_404(Forum, pk=forum_id)
    if thread_id:
        thread = get_object_or_404(Post, pk=thread_id)
    else:
        thread = None

    if request.method == "POST":
        form = PostForm(request.POST)
        form.fields['title'].required = not thread

        if form.is_valid():
            new_post = form.save(commit=False)
            new_post.author = request.forum_user
            new_post.author_ip = request.META.get('HTTP_X_FORWARDED_FOR')
            if not new_post.author_ip:
                new_post.author_ip = request.META.get('REMOTE_ADDR')

            if thread:
                new_post.parent_post = thread
                if request.user.has_perm('forum.change_post'):
                    thread.sticky = new_post.sticky
                    thread.locked = new_post.locked
                    thread.save()
                new_post.sticky = False
                new_post.locked = False
                new_post.reply_num = thread.reply_count

            else:
                new_post.parent_forum = forum
                if not request.user.has_perm('forum.change_post'):
                    new_post.sticky = False
                    new_post.locked = False

            new_post.save()
            return HttpResponseRedirect(new_post.get_absolute_url())

    else:
        form = PostForm()
        if thread:
            form.fields['sticky'].initial = thread.sticky
            form.fields['locked'].initial = thread.locked

    return render_response(request,
            'counterpoint/new_post.html',
            {'form': form, 'forum': forum, 'thread': thread})

new_post = login_required(new_post)


def edit(request, post_id):
    post = get_object_or_404(Post, pk=post_id)
    if post.parent_forum:
        forum = post.parent_forum
        thread = None
    else:
        forum = post.parent_post.parent_forum
        thread = post.parent_post

    if not request.user.has_perm('forum.change_post') and \
           request.forum_user != post.author:
        raise Http403('You can only edit your own posts.')

    edit_limit = timedelta(minutes=settings.EDIT_LIMIT)
    timesince = datetime.now() - post.posted
    if timesince > edit_limit:
        raise Http403('You can only edit posts within %d minutes of posting.' % settings.EDIT_LIMIT)

    if request.method == "POST":
        form = PostForm(request.POST, instance=post)
        form.fields['title'].required = not thread

        if form.is_valid():
            post = form.save(commit=False)
            post.edited = True
            post.edit_time = datetime.now()
            post.edited_by = request.user.forumuser_set.all()[0].nickname

            if thread and request.user.has_perm('forum.change_post'):
                thread.sticky = post.sticky
                thread.locked = post.locked
                thread.save()

            else:
                post.sticky = False
                post.locked = False

            post.save()
            return HttpResponseRedirect(post.get_absolute_url())

    else:
        form = PostForm(instance=post)

    return render_response(request,
            'counterpoint/new_post.html',
            {'form': form, 'forum': forum, 'thread': thread})

edit = login_required(edit)


def edit_user(request, user_id):
    forum_user = get_object_or_404(ForumUser, pk=user_id)
    if not request.user.has_perm('forum.change_forumuser') and \
           request.user.id != forum_user.user.id:
        raise Http403('You are only allowed to edit your own profile.')

    if request.method == "POST":
        form = ForumUserForm(request.POST, instance=forum_user)
        if form.is_valid():
            forum_user = form.save()
            return HttpResponseRedirect(forum_user.get_absolute_url())
    else:
        form = ForumUserForm(instance=forum_user)

    return render_response(request,
            'counterpoint/edit_user.html',
            {'form': form, 'object': forum_user})

edit_user = login_required(edit_user)
